#pragma once

#define TBuf ((T*)m_buf)

template <typename T, uint32 bufsize> struct fixedvector
{
#ifdef _DEBUG
	T* list;
#endif
	fixedvector()
	{
#ifdef _DEBUG
		list=(T*)m_buf;
#endif
		m_size=0;
	}

	~fixedvector()
	{
		for (uint32 n=0; n<m_size;++n)
			TBuf[n].~T();
	}

	fixedvector(const fixedvector& i_other)
	{
#ifdef _DEBUG
		list=(T*)m_buf;
#endif
		m_size=i_other.m_size;

		for (uint32 n=0; n<m_size; ++n)
			new (&(((T*)m_buf)[n])) T(((T*)i_other.m_buf)[n]);
	}

	void operator=(const fixedvector& i_other)
	{
		for (uint32 n=0; n<m_size;++n)
			TBuf[n].~T();

		m_size=i_other.m_size;

		for (uint32 n=0; n<m_size; ++n)
			new ((&((T*)m_buf)[n])) T(((T*)i_other.m_buf)[n]);
	}

	uint32 size() const
	{
		return m_size;
	}

	uint32 capacity() const
	{
		return bufsize;
	}

	void resize(uint32 i_newsize)
	{
		if (m_size<i_newsize)
			for (uint32 n=m_size; n<i_newsize; ++n)
				new (&TBuf[n]) T();
		else
			for (uint32 n=i_newsize; n<m_size; ++n)
				TBuf[n].~T();

		m_size=i_newsize;
	}

	void clear()
	{
#if 1
		for (uint32 n=0; n<m_size;++n)
			TBuf[n].~T();

		m_size=0;
#endif
	}

	void push_back(const T& i_elem)
	{
		ASSERTTXT(m_size<bufsize,"vector is full");
		new (&TBuf[m_size++]) T(i_elem);
	}

	void pop_back()
	{
		ASSERTTXT(m_size>0,"vector is empty");
		TBuf[--m_size].~T();
	}

	void pop_front()
	{
		ASSERTTXT(m_size>0,"vector is empty");
		for (uint32 n=0; n<m_size-1; ++n)
		{
			TBuf[n]=TBuf[n+1];
		}
		TBuf[--m_size].~T();
	}
	T& operator[](uint32 i_index)
	{
		ASSERTTXT(i_index<m_size,_str("wrong index:%d size: %d",i_index,m_size));
		return TBuf[i_index];
	}

	const T& operator[](uint32 i_index) const
	{
		ASSERTTXT(i_index<m_size,_str("wrong index:%d size: %d",i_index,m_size));
		//			ASSERTTXT(i_index<m_size,"wrong index");
		return TBuf[i_index];
	}

	T& back()
	{
		ASSERTTXT(m_size>0,"vector is empty");
		return TBuf[m_size-1];
	}

	const T& back() const
	{
		ASSERTTXT(m_size>0,"vector is empty");
		return TBuf[m_size-1];
	}


	static const fixedvector& emptyvector()
	{
		static const fixedvector v; return v;
	}

	uint8 m_buf[bufsize*sizeof(T)];
	uint32 m_size;
};
